<?php

namespace App\Services;

use App\Models\Bar;
use App\Models\Favorite;
use App\Models\Post;
use App\Models\PostLike;
use App\Models\User;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class PostService
{
    /**
     * 发布帖子
     */
    public function createPost(Bar $bar, User $user, array $data): Post
    {
        return DB::transaction(function () use ($bar, $user, $data) {
            // 检查用户是否为贴吧成员（只有成员才能发帖）
            if (! $bar->isMember($user) && ! $bar->isOwner($user)) {
                throw new \Exception('您不是本贴吧成员，无法发帖');
            }

            // 处理图片上传
            $images = [];
            if (isset($data['images']) && is_array($data['images'])) {
                foreach ($data['images'] as $image) {
                    if ($image instanceof \Illuminate\Http\UploadedFile) {
                        $images[] = $image->store('posts', 'public');
                    }
                }
            }

            // 创建帖子（slug 将由模型的 boot 方法自动生成）
            $post = Post::create([
                'title' => $data['title'],
                'slug' => $data['slug'] ?? null, // 模型会自动生成
                'content' => $data['content'],
                'user_id' => $user->id,
                'bar_id' => $bar->id,
                'images' => ! empty($images) ? $images : null,
                'views' => 0,
                'like_count' => 0,
                'reply_count' => 0,
                'is_pinned' => false,
                'is_essence' => false,
            ]);

            // 更新贴吧帖子数
            $bar->increment('post_count');

            // 增加用户经验值（发帖奖励）
            $user->increment('exp', 5);

            return $post->load('user', 'bar');
        });
    }

    /**
     * 获取首页帖子列表（不限贴吧，支持多种排序方式）
     *
     * @param  string  $sort  排序方式：following（关注）、recommended（推荐）、hot（热门）、latest（最新）
     * @param  int  $perPage  每页数量
     * @param  User|null  $user  当前用户（用于批量加载点赞和收藏状态，以及获取关注贴吧）
     * @return LengthAwarePaginator
     */
    public function getHomePostsList(string $sort = 'hot', int $perPage = 15, ?User $user = null): LengthAwarePaginator
    {
        $query = Post::with(['user', 'bar']);

        // 如果用户已登录，批量预加载用户的点赞和收藏关系
        if ($user) {
            $query->with([
                'likes' => function ($q) use ($user) {
                    $q->where('user_id', $user->id);
                },
                'favorites' => function ($q) use ($user) {
                    $q->where('user_id', $user->id);
                },
            ]);
        }

        // 根据排序方式构建查询
        switch ($sort) {
            case 'hot':
                // 热度排序：未登录用户显示热门贴吧的帖子，已登录用户显示全站热门
                if (!$user) {
                    // 未登录用户：只显示热门贴吧的帖子
                    $popularBarIds = \App\Models\Bar::orderBy('member_count', 'desc')
                        ->orderBy('post_count', 'desc')
                        ->limit(10) // 取前10个热门贴吧
                        ->pluck('id');

                    if ($popularBarIds->isNotEmpty()) {
                        $query->whereIn('bar_id', $popularBarIds);
                    }
                }
                // 置顶优先，然后按点赞数+浏览数+回复数排序
                $query->orderBy('is_pinned', 'desc')
                    ->orderByRaw('(like_count * 3 + views + reply_count * 2) desc')
                    ->orderBy('created_at', 'desc');
                break;

            case 'latest':
                // 最新排序：置顶优先，然后按时间排序
                $query->orderBy('is_pinned', 'desc')
                    ->orderBy('created_at', 'desc');
                break;

            case 'following':
                // 关注排序：显示用户关注的贴吧的热门帖子
                if ($user) {
                    $barIds = $user->joinedBars()->pluck('bars.id');
                    if ($barIds->isEmpty()) {
                        // 如果用户没有关注任何贴吧，返回空结果
                        $query->whereRaw('1 = 0');
                    } else {
                        $query->whereIn('bar_id', $barIds);
                        // 按热度排序：置顶优先，然后按点赞数+浏览数+回复数排序
                        $query->orderBy('is_pinned', 'desc')
                            ->orderByRaw('(like_count * 3 + views + reply_count * 2) desc')
                            ->orderBy('created_at', 'desc');
                    }
                }
                break;

            case 'recommended':
                // 推荐排序：先显示关注贴吧的热门帖子，然后是推荐的帖子
                if ($user) {
                    $barIds = $user->joinedBars()->pluck('bars.id');
                    // 使用优先级排序：关注贴吧的帖子优先级更高
                    if ($barIds->isNotEmpty()) {
                        $query->orderByRaw('CASE WHEN bar_id IN (' . $barIds->implode(',') . ') THEN 0 ELSE 1 END')
                            ->orderBy('is_pinned', 'desc')
                            ->orderByRaw('(like_count * 2 + views * 0.5 + reply_count * 1.5) / POW(TIMESTAMPDIFF(HOUR, created_at, NOW()) + 2, 1.5) desc')
                            ->orderBy('created_at', 'desc');
                    } else {
                        // 如果没有关注任何贴吧，直接使用推荐算法
                        $query->orderBy('is_pinned', 'desc')
                            ->orderByRaw('(like_count * 2 + views * 0.5 + reply_count * 1.5) / POW(TIMESTAMPDIFF(HOUR, created_at, NOW()) + 2, 1.5) desc')
                            ->orderBy('created_at', 'desc');
                    }
                } else {
                    // 未登录用户不应该看到推荐，但这作为备用逻辑
                    $query->orderBy('is_pinned', 'desc')
                        ->orderByRaw('(like_count * 2 + views * 0.5 + reply_count * 1.5) / POW(TIMESTAMPDIFF(HOUR, created_at, NOW()) + 2, 1.5) desc')
                        ->orderBy('created_at', 'desc');
                }
                break;

            default:
                // 默认使用热门排序
                $query->orderBy('is_pinned', 'desc')
                    ->orderByRaw('(like_count * 3 + views + reply_count * 2) desc')
                    ->orderBy('created_at', 'desc');
                break;
        }

        $posts = $query->paginate($perPage);

        // 批量标记点赞和收藏状态（基于预加载的关系）
        if ($user) {
            $posts->getCollection()->transform(function ($post) {
                $post->is_liked = $post->likes->isNotEmpty();
                $post->is_favorited = $post->favorites->isNotEmpty();
                unset($post->likes);
                unset($post->favorites);
                return $post;
            });
        } else {
            $posts->getCollection()->transform(function ($post) {
                $post->is_liked = false;
                $post->is_favorited = false;
                return $post;
            });
        }

        return $posts;
    }

    /**
     * 获取帖子列表（支持排序、分页）
     *
     * @param  Bar  $bar  贴吧
     * @param  string|null  $sort  排序方式：latest（最新）、hot（热度）、essence（精华）
     * @param  int  $perPage  每页数量
     * @param  User|null  $user  当前用户（用于批量加载点赞和收藏状态）
     */
    public function getPostsList(Bar $bar, ?string $sort = 'latest', int $perPage = 15, ?User $user = null): LengthAwarePaginator
    {
        $query = Post::with(['user', 'bar'])
            ->where('bar_id', $bar->id);

        // 如果用户已登录，批量预加载用户的点赞和收藏关系
        if ($user) {
            $query->with([
                'likes' => function ($q) use ($user) {
                    $q->where('user_id', $user->id);
                },
                'favorites' => function ($q) use ($user) {
                    $q->where('user_id', $user->id);
                },
            ]);
        }

        // 根据排序方式构建查询
        switch ($sort) {
            case 'hot':
                // 热度排序：置顶优先，然后按点赞数+浏览数+回复数排序
                $query->orderBy('is_pinned', 'desc')
                    ->orderByRaw('(like_count * 3 + views + reply_count * 2) desc')
                    ->orderBy('created_at', 'desc');
                break;
            case 'essence':
                // 精华排序：置顶优先，精华优先
                $query->orderBy('is_pinned', 'desc')
                    ->orderBy('is_essence', 'desc')
                    ->orderBy('created_at', 'desc');
                break;
            case 'latest':
            default:
                // 最新排序：置顶优先，然后按创建时间
                $query->orderBy('is_pinned', 'desc')
                    ->orderBy('created_at', 'desc');
                break;
        }

        $posts = $query->paginate($perPage);

        // 批量标记点赞和收藏状态（基于预加载的关系）
        if ($user) {
            $posts->getCollection()->transform(function ($post) {
                $post->is_liked = $post->likes->isNotEmpty();
                $post->is_favorited = $post->favorites->isNotEmpty();
                // 清理预加载的关系，避免数据冗余
                unset($post->likes);
                unset($post->favorites);

                return $post;
            });
        }

        return $posts;
    }

    /**
     * 获取帖子详情
     */
    public function getPostDetail(Post $post): Post
    {
        // 增加浏览数
        $post->incrementViews();

        return $post->load(['user', 'bar', 'likes.user', 'favorites.user']);
    }

    /**
     * 点赞/取消点赞帖子
     */
    public function toggleLike(Post $post, User $user): bool
    {
        return DB::transaction(function () use ($post, $user) {
            $existingLike = PostLike::where('post_id', $post->id)
                ->where('user_id', $user->id)
                ->first();

            if ($existingLike) {
                // 取消点赞
                $existingLike->delete();
                $post->decrement('like_count');

                return false; // 已取消点赞
            } else {
                // 点赞
                PostLike::create([
                    'post_id' => $post->id,
                    'user_id' => $user->id,
                ]);
                $post->increment('like_count');

                // 增加作者经验值（被点赞奖励）
                $post->user->increment('exp', 2);

                return true; // 已点赞
            }
        });
    }

    /**
     * 收藏/取消收藏帖子
     */
    public function toggleFavorite(Post $post, User $user): bool
    {
        return DB::transaction(function () use ($post, $user) {
            $existingFavorite = Favorite::where('post_id', $post->id)
                ->where('user_id', $user->id)
                ->first();

            if ($existingFavorite) {
                // 取消收藏
                $existingFavorite->delete();

                return false; // 已取消收藏
            } else {
                // 收藏
                Favorite::create([
                    'post_id' => $post->id,
                    'user_id' => $user->id,
                ]);

                // 增加作者经验值（被收藏奖励）
                $post->user->increment('exp', 3);

                return true; // 已收藏
            }
        });
    }

    /**
     * 更新帖子信息
     */
    public function updatePost(Post $post, User $user, array $data): Post
    {
        return DB::transaction(function () use ($post, $user, $data) {
            // 检查权限：只有作者可以编辑
            if (! $post->isAuthor($user)) {
                throw new \Illuminate\Auth\Access\AuthorizationException('您无权编辑此帖子');
            }

            // 处理图片上传
            if (isset($data['images']) && is_array($data['images'])) {
                $images = [];
                foreach ($data['images'] as $image) {
                    if ($image instanceof \Illuminate\Http\UploadedFile) {
                        $images[] = $image->store('posts', 'public');
                    }
                }
                $data['images'] = ! empty($images) ? $images : $post->images;
            }

            $post->update($data);

            return $post->fresh();
        });
    }

    /**
     * 删除帖子
     */
    public function deletePost(Post $post, User $user): bool
    {
        return DB::transaction(function () use ($post, $user) {
            // 检查权限：作者或吧主可以删除
            $canDelete = $post->isAuthor($user)
                || $post->bar->isOwner($user)
                || $user->isAdmin();

            if (! $canDelete) {
                throw new \Illuminate\Auth\Access\AuthorizationException('您无权删除此帖子');
            }

            // 删除图片
            if ($post->images && is_array($post->images)) {
                foreach ($post->images as $image) {
                    if (Storage::disk('public')->exists($image)) {
                        Storage::disk('public')->delete($image);
                    }
                }
            }

            // 更新贴吧帖子数
            $post->bar->decrement('post_count');

            // 删除帖子（关联的点赞和收藏会通过外键级联删除）
            return $post->delete();
        });
    }

    /**
     * 置顶/取消置顶帖子（仅吧主可操作）
     */
    public function togglePin(Post $post, User $user): bool
    {
        return DB::transaction(function () use ($post, $user) {
            // 检查权限：只有吧主可以置顶
            if (! $post->bar->isOwner($user) && ! $user->isAdmin()) {
                throw new \Illuminate\Auth\Access\AuthorizationException('您无权置顶此帖子');
            }

            $post->update([
                'is_pinned' => ! $post->is_pinned,
                'pinned_at' => ! $post->is_pinned ? now() : null,
            ]);

            return $post->is_pinned;
        });
    }

    /**
     * 加精/取消精华（仅吧主可操作）
     */
    public function toggleEssence(Post $post, User $user): bool
    {
        return DB::transaction(function () use ($post, $user) {
            // 检查权限：只有吧主可以加精
            if (! $post->bar->isOwner($user) && ! $user->isAdmin()) {
                throw new \Illuminate\Auth\Access\AuthorizationException('您无权设置此帖子为精华');
            }

            $post->update([
                'is_essence' => ! $post->is_essence,
            ]);

            return $post->is_essence;
        });
    }

    /**
     * 获取用户的帖子列表
     *
     * @param  User  $user  用户
     * @param  int  $perPage  每页数量
     * @param  User|null  $currentUser  当前登录用户（用于批量加载点赞和收藏状态）
     */
    public function getUserPosts(User $user, int $perPage = 15, ?User $currentUser = null): LengthAwarePaginator
    {
        $query = Post::with(['user', 'bar'])
            ->where('user_id', $user->id);

        // 如果当前用户已登录，批量预加载点赞和收藏关系
        if ($currentUser) {
            $query->with([
                'likes' => function ($q) use ($currentUser) {
                    $q->where('user_id', $currentUser->id);
                },
                'favorites' => function ($q) use ($currentUser) {
                    $q->where('user_id', $currentUser->id);
                },
            ]);
        }

        $posts = $query->orderBy('created_at', 'desc')->paginate($perPage);

        // 批量标记点赞和收藏状态
        if ($currentUser) {
            $posts->getCollection()->transform(function ($post) {
                $post->is_liked = $post->likes->isNotEmpty();
                $post->is_favorited = $post->favorites->isNotEmpty();
                unset($post->likes);
                unset($post->favorites);

                return $post;
            });
        }

        return $posts;
    }

    /**
     * 获取用户的收藏列表
     *
     * @param  User  $user  用户
     * @param  int  $perPage  每页数量
     * @param  User|null  $currentUser  当前登录用户（用于批量加载点赞和收藏状态）
     */
    public function getUserFavorites(User $user, int $perPage = 15, ?User $currentUser = null): LengthAwarePaginator
    {
        $query = Post::with(['user', 'bar'])
            ->whereHas('favorites', function ($q) use ($user) {
                $q->where('user_id', $user->id);
            });

        // 如果当前用户已登录，批量预加载点赞和收藏关系
        if ($currentUser) {
            $query->with([
                'likes' => function ($q) use ($currentUser) {
                    $q->where('user_id', $currentUser->id);
                },
                'favorites' => function ($q) use ($currentUser) {
                    $q->where('user_id', $currentUser->id);
                },
            ]);
        }

        $posts = $query->orderBy('created_at', 'desc')->paginate($perPage);

        // 批量标记点赞和收藏状态
        if ($currentUser) {
            $posts->getCollection()->transform(function ($post) {
                $post->is_liked = $post->likes->isNotEmpty();
                $post->is_favorited = $post->favorites->isNotEmpty();
                unset($post->likes);
                unset($post->favorites);

                return $post;
            });
        }

        return $posts;
    }
}
